package MRDemo;

import org.apache.hadoop.io.Writable;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.math.BigDecimal;

/*
 * 序列化与反序列化
 * 序列化：将对象转换为字节序列的过程，将人能看懂的数据转化为计算机能看懂的数据（二进制）
 * 反序列化：将字节序列恢复为对象的过程，将计算机能看懂的数据转化为人能看懂的数据
 * 序列化与反序列化的作用：实现数据的持久化，在网络中传输
 */
/*
 * 自定义序列化过程，Hadoop提供了一个方式，提供一个接口：Writable，实现该接口，重写其中的方法
 * 实现Writable接口就必须要要重写两个方法：write、readFields
 */
/*
 * 流程：
 * 1、创建一个自定义类，继承Writable接口-->重写两个方法：write、readFields
 * 2、设置需要传递的数据，将其设置为私有类型
 *   为什么将数据定义为私有类型：外部可以访问，但是修改是受到限制的
 *   如何给私有类型赋值？就必须调用公共的get和set方法才能够给私有类型赋值
 * 3、获得赋值：通过构造方法进行赋值
 *   BigDecimal类型：不可变的数据，为了高精度计算;保证高精度传递，BigDecimal类型推荐使用String类型进行传递
 * 4、定义序列化与反序列化过程,一定要注意顺序问题：序列化中输出顺序是怎么样的，那么反序列化中读到的顺序就是怎么样的
 * 5、定义value的输出，重写toString方法
 */
public class bean implements Writable {
    //定义传递的数据
    private String device_id;
    private BigDecimal price_self, price_other, price_total;

    //无参构造方法，为了能够方便调用bean方法
//    public bean() {
//    }

    //含参构造方法
    public bean(String device_id, BigDecimal price_self, BigDecimal price_other) {
        this.device_id = device_id;
        this.price_self = price_self;
        this.price_other = price_other;
        this.price_total = this.price_self.add(this.price_other);
    }

    @Override
    public void write(DataOutput out) throws IOException {
        //序列化过程
        //MR通过了序列化方法，只需要按照数据类型进行传递即可，方法名称为write*****
        //第一个写的数据
        out.writeUTF(device_id);
        out.writeUTF(price_self.toPlainString());
        out.writeUTF(price_other.toPlainString());
        out.writeUTF(price_total.toPlainString());
    }

    @Override
    public void readFields(DataInput in) throws IOException {
        //反序列化过程
        //第一个输出
        this.device_id = in.readUTF();
        this.price_self = new BigDecimal(in.readUTF());
        this.price_other = new BigDecimal(in.readUTF());
        this.price_total = new BigDecimal(in.readUTF());
    }

//    public String getDevice_id() {
//        return device_id;
//    }

//    public void setDevice_id(String device_id) {
//        this.device_id = device_id;
//    }

    public BigDecimal getPrice_self() {
        return price_self;
    }

//    public void setPrice_self(BigDecimal price_self) {
//        this.price_self = price_self;
//    }

    public BigDecimal getPrice_other() {
        return price_other;
    }

//    public void setPrice_other(BigDecimal price_other) {
//        this.price_other = price_other;
//    }

//    public BigDecimal getPrice_total() {
//        return price_total;
//    }
//
//    public void setPrice_total(BigDecimal price_total) {
//        this.price_total = price_total;
//    }

    @Override
    //结果样式：device_id    price_self  price_other price_total
    //使用制表符来保障数据格式一致
    public String toString() {
        return price_self + "\t" + price_other + "\t" + price_total;
    }
}
